package com.jlju.djmhadmin.controller;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.jlju.djmhadmin.common.Enums.IdentityEnums;
import com.jlju.djmhadmin.common.Enums.StudentStatusEnums;
import com.jlju.djmhadmin.common.Enums.UserStatusEnums;
import com.jlju.djmhadmin.common.GenericResponse;
import com.jlju.djmhadmin.common.util.*;
import com.jlju.djmhadmin.dao.common.util.MailUtil;
import com.jlju.djmhadmin.dao.common.util.UUIDUtils;
import com.jlju.djmhadmin.dao.entity.Student;
import com.jlju.djmhadmin.dao.entity.User;
import com.jlju.djmhadmin.dao.service.StudentService;
import com.jlju.djmhadmin.dao.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.Callable;

/**
 * All rights Reserved, Designed By Liting.
 *
 * @description: 学生信息相关controller
 * @author: LiTing[liting08011@163.com]
 * @create: 2018-04-19 17:51
 * @Copyright ©2018 Liting. All rights reserved.
 * 注意：本内容仅限于吉林建筑大学ACM协会内部传阅，禁止外泄以及用于其他的商业用途。
 **/
@Slf4j
@RestController
@RequestMapping("/student")
@Api("学生相关信息操作")
public class StudentController {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private StudentService studentService;

    @Autowired
    private UserService userService;

    /**
    * @Description: 验证学生信息是否正确以及是否符合未注册标准
    * @Param:
    * @return:
    * @Author: LiTing [liting08011@163.com]
    * @Date: 2018/4/24
    * @Time: 上午9:59
    */
    public Boolean valid(String cardId) throws Exception {
        logger.info("***学生注册核验信息开始***");
        //根据身份证号去核验学生的信息，新生且未报道注册
        Student student = studentService.getByCard(cardId);
        if(null == student) {
            throw new Exception("对不起，未查询到相关信息，请重新验证");
        } else if(!student.getStatus().equals(StudentStatusEnums.beReported.getValue())) {
            throw new Exception("对不起，该生已注册完毕 ！");
        } else {
            return true;
        }
    }

    @ApiOperation("新生注册")
    @RequestMapping(value = "/update")
    @RequiredStringValidator(fieldName="cardId",trim=true,errCode="ACM9900",errMsg="请求参数不足,身份证号不能为空")
    public Callable<GenericResponse<String>> update(@RequestBody String json) {
        Student student = JsonUtil.jsonToObject(json,Student.class);
        logger.info("***学生信息更新开始***");
        try {
            //进行信息核验
            this.valid(student.getCardId());
            //核验结束执行更新
            student.setCreateDate(new Date().toString());
            if(!ValidatorUtil.isEmail(student.getEmail())) {
                throw new Exception("邮箱格式不正确");
            }
            if (!ValidatorUtil.isMobile(student.getPhone()) || !ValidatorUtil.isMobile(student.getParPhone())) {
                throw new Exception("手机号格式不正确");
            }
            student.setStatus(StudentStatusEnums.reading.getValue());
            this.studentService.updateById(student);
            //获取学生信息， 注册门户登陆账户
            Student finalStudent = this.studentService.getByCard(student.getCardId());
//            User user = new User(finalStudent.getAcNo(), finalStudent.getName(), finalStudent.getEmail(), finalStudent.getPhone());
//            user.setPassword("123456");
//            user.setIdentity(IdentityEnums.students.getValue());
//            user.setStatus(UserStatusEnums.normal.getValue());
//            this.userService.add(user);
            logger.info("***学生信息更新成功***");
            try {
                MailUtil mailUtil = new MailUtil();
                mailUtil.postMail(finalStudent.getEmail(), "新生注册成功---学号--" + finalStudent.getAcNo() + "姓名" + finalStudent.getName() + "班级" + finalStudent.getClassName() + "请于指定报道时间到校报道");
            } catch (Exception e) {
                logger.error("***新生注册成功，未发送邮件***");
            }
            return () -> GenericResponse.success("ACM0200", "注册成功", student);
        } catch (Exception e) {
            logger.error("***学生信息更新失败***" + e);
            return () -> GenericResponse.failed("ACM0201", "注册失败");
        }
    }

    @ApiOperation("注销学籍")
    @RequestMapping(value = "/delete")
    @RequiredStringValidator(fieldName="uuid",trim=true,errCode="ACM0210",errMsg="请求参数不足,uuid不能为空")
    public Callable<GenericResponse<String>> delete(@RequestBody String json) {
        logger.info("***学生学籍注销开始***入参 " + json);
        try {
            json = StringUtils.trimFirstAndLastChar(json,'\"');
            Student student = new Student(json);
            this.studentService.deleteById(student);
            Student finalStudent = this.studentService.findOneById(student.getUuid());
            logger.info("***学生学籍注销成功***");
            try {
                MailUtil mailUtil = new MailUtil();
                mailUtil.postMail("liting08011@163.com", "学籍注销成功， 学号： " + finalStudent.getAcNo() + "姓名 ：" + finalStudent.getName());
            } catch (Exception e) {
                logger.error("学籍注销成功，邮件发送失败");
            }
            return () -> GenericResponse.success("ACM0202", "学籍注销成功", finalStudent);
        } catch (Exception e) {
            logger.info("***学生学籍注销失败***" + e);
            return () -> GenericResponse.failed("ACM0203", "学籍注销失败");
        }
    }


    @ApiOperation("新增学籍")
    @Validations(requiredStrings={
            @RequiredStringValidator(fieldName="name",errCode="ACM0204",errMsg="请求参数不足,姓名不能为空"),
            @RequiredStringValidator(fieldName="sex",errCode="ACM0205",errMsg="请求参数不足，性别不能为空"),
            @RequiredStringValidator(fieldName="className",errCode="ACM0206",errMsg="请求参数不足，班级不能为空"),
            @RequiredStringValidator(fieldName="acNo",errCode="ACM0207",errMsg="请求参数不足，学号不能为空"),
            @RequiredStringValidator(fieldName="cardId",errCode="ACM0208",errMsg="请求参数不足，身份证号不能为空"),
            @RequiredStringValidator(fieldName="classLevel",errCode="ACM0209",errMsg="请求参数不足，级别不能为空")
    })
    @RequestMapping(value = "/add")
    public Callable<GenericResponse<String>> add(@RequestBody String json) {
        logger.info("***学生学籍添加开始***入参 ： " + json);
        try {
            Student student = JsonUtil.jsonToObject(json,Student.class);
            if (ValidatorUtil.isIDCard(student.getCardId())) {
                throw new Exception("身份证号不正确");
            }
            this.studentService.add(student);
            logger.info("***学生学籍添加成功***" + student);
            return () -> GenericResponse.success("ACM0008", "添加成功", student);
        } catch (Exception e) {
            logger.info("***学生学籍添加失败***" + e);
            return () -> GenericResponse.failed("ACM0009", "添加失败" + e);
        }
    }



    @ApiOperation("查看详细学籍学籍")
    @RequestMapping(value = "/findOneById")
    public Callable<GenericResponse<String>> findOneById(@RequestBody String json) {
        logger.info("***学生学籍查询开始***");
        try {
            Student student = JsonUtil.jsonToObject(json,Student.class);
            Student finalStudent = this.studentService.findOneById(student.getAcNo());
            logger.info("***学生学籍查询成功***");
            return () -> GenericResponse.success("ACM0012", "详细查询成功", finalStudent);
        } catch (Exception e) {
            return () -> GenericResponse.failed("ACM0013", "查询详情失败" + e);
        }
    }


    @ApiOperation("查看全部学生，带分页")
    @RequestMapping(value = "/findAll")
    public Callable<GenericResponse<List<Student>>> findAll(@RequestBody String json, int pageNum, int pageSize) {
        logger.info("***查看全部学生信息（分页）***");
        try {
            Student student = JsonUtil.jsonToObject(json,Student.class);
            PageHelper.startPage(pageNum, pageSize);
            List<Student> list = this.studentService.findAll(student);
            // 用PageInfo对结果进行包装
            PageInfo pageInfo = new PageInfo(list);
            logger.info("***查看全部学生信息（分页） 成功***" + pageInfo);
            return () -> GenericResponse.success("ACM0010", "查询成功", pageInfo);
        } catch (Exception e) {
            logger.info("***查看全部学生信息（分页）失败***" + e);
            return () -> GenericResponse.failed("ACM0011", "查询失败");
        }
    }

    @ApiOperation("批量导入学生")
    @RequestMapping(value = "/readExcelFile")
    public String readExcelFile(MultipartFile file) {
        logger.info("***批量导入学生信息开始***");
        if(StringUtils.isEmpty(file)) {
            logger.error("请选择文件");
            return "请选择文件";
        }
        try {
            long t = System.currentTimeMillis();
            String result = "";
            //创建处理EXCEL的类
            ReadExcel readExcel = new ReadExcel();
            //解析excel，获取上传的事件单
            List<Student> superviseList = readExcel.getExcelInfo(file);
            //至此已经将excel中的数据转换到list里面了,接下来就可以操作list,可以进行保存到数据库,或者其他操作.
            //执行批量添加
            for (int i = 0; i < superviseList.size(); i++) {
                studentService.add(superviseList.get(i));
            }
            long t2 = System.currentTimeMillis();
            //和你具体业务有关,这里不做具体的示范
            logger.info("上传成功: 耗时 ： " + (t2-t));
            return "上传成功";
        } catch (Exception e) {
            logger.error("上传失败");
            return "上传失败";
        }
    }

    @ApiOperation("新生注册")
    @RequestMapping(value = "/updateById")
    @RequiredStringValidator(fieldName="cardId",trim=true,errCode="ACM9900",errMsg="请求参数不足,身份证号不能为空")
    public Callable<GenericResponse<String>> updateById(@RequestBody String json) {
        logger.info("***学生信息更新开始***入参：" + json);
        Student student = JsonUtil.jsonToObject(json,Student.class);
        try {
            try {
                this.studentService.updateById(student);
            } catch (Exception e) {
                logger.error("***学生信息更新失败***");
                throw new Exception("生信息更新失败");
            }
            logger.info("***学生信息更新成功***");
            return () -> GenericResponse.success("ACM0014", "更新成功", student);
        } catch (Exception e) {
            logger.error("***学生信息更新失败***" + e);
            return () -> GenericResponse.failed("ACM0015", "更新失败");
        }
    }

    @ApiOperation("学籍信息导出")
    @RequestMapping(value = "/export")
    @RequiredStringValidator(fieldName="cardId",trim=true,errCode="ACM9900",errMsg="请求参数不足,身份证号不能为空")
    public void export(HttpServletRequest request, HttpServletResponse response) {
        logger.info("***学生信息导出***入参：");
        try {
            Student student = new Student();
            List<Student> list = this.studentService.findAll(student);
            OutputStream out = new BufferedOutputStream(response.getOutputStream());
            ToExcel.createExcel(list,out,response);
            logger.info("***学籍信息批量导出成功***");
        } catch (Exception e) {
            logger.error("***学籍信息导出失败***" + e);
        }
    }

}